/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.metadataRepository.sysnoSignatureMapping;

import cz.mzk.kramerius.commons.Dom4jUtils;
import cz.mzk.oai.metadataRepository.repository.AlephBase;
import cz.mzk.oai.metadataRepository.repository.Identifier;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;

/**
 *
 * @author Martin Řehánek (rehan at mzk.cz)
 */
public class XmlMappingsLoader implements MappingsLoader {

    private final XPath recordsXpath = DocumentHelper.createXPath("/mappings/record");
    private final XPath idXpath = DocumentHelper.createXPath("id");
    private final XPath baseXpath = DocumentHelper.createXPath("base");
    private final XPath sysnoXpath = DocumentHelper.createXPath("sysno");
    private final XPath signatureXpath = DocumentHelper.createXPath("signature");
    private final File mappingFile;
    private final List<Mapping> mappings = new ArrayList<Mapping>();

    public XmlMappingsLoader(File mappingFile) {
        this.mappingFile = mappingFile;
    }

    public List<Mapping> loadMappings() {
        try {
            Document doc = Dom4jUtils.loadDocument(mappingFile, false);
            loadMappings(doc);
            return mappings;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(XmlMappingsLoader.class.getName()).log(Level.SEVERE, null, ex);
            return Collections.<Mapping>emptyList();
        } catch (IOException ex) {
            Logger.getLogger(XmlMappingsLoader.class.getName()).log(Level.SEVERE, null, ex);
            return Collections.<Mapping>emptyList();
        } catch (DocumentException ex) {
            Logger.getLogger(XmlMappingsLoader.class.getName()).log(Level.SEVERE, null, ex);
            return Collections.<Mapping>emptyList();
        }

    }

    private void loadMappings(Document doc) {
        List<Element> records = recordsXpath.selectNodes(doc);
        for (Element recordEl : records) {
            loadMapping(recordEl);
        }
    }

    private void loadMapping(Element recordEl) {
        Identifier id = loadIdentifier(recordEl);
        String signature = loadSignature(recordEl);
        Mapping mapping = new Mapping(id, signature);
        mappings.add(mapping);
    }

    private Identifier loadIdentifier(Element recordEl) {
        Element idEl = (Element) idXpath.selectSingleNode(recordEl);
        String baseStr = loadBase(idEl);
        AlephBase base = AlephBase.valueOf(baseStr);
        String sysno = loadSysno(idEl);
        return new Identifier(base, sysno);
    }

    private String loadBase(Element idEl) {
        return getContent(idEl, baseXpath);
    }

    private String getContent(Element element, XPath xpath) {
        Node node = xpath.selectSingleNode(element);
        return node.getText();
    }

    private String loadSysno(Element idEl) {
        return getContent(idEl, sysnoXpath);
    }

    private String loadSignature(Element recordEl) {
        return getContent(recordEl, signatureXpath);
    }
}
